﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml;
using System.IO;

namespace Catalogue
{
    class Catalogue
    {
        const string XML_DOCUMENT = "catalogue.xml";
        private static Dictionary<string, List<string>> artistsAndAlbums = new Dictionary<string, List<string>>();

        public static void WriteToXMLFile()
        {
            XElement firstAlbum =
             new XElement("albums",
                 new XElement("album",
                     new XElement("name", "Unchain my heart"),
                     new XElement("artist", "Joe Cocker"),
                     new XElement("year", "1995"),
                     new XElement("producer", "Sony Music"),
                     new XElement("price", "30.5"),
                     new XElement("songs",
                         new XElement("title", "song1"),
                         new XElement("duration", "154"),
                         new XElement("title", "song2"),
                         new XElement("duration", "166"),
                         new XElement("title", "song3"),
                         new XElement("duration", "188"))
                         ),
                          new XElement("album",
                     new XElement("name", "Unchain my heart"),
                     new XElement("artist", "Joe Cocker"),
                     new XElement("year", "1995"),
                     new XElement("producer", "Sony Music"),
                     new XElement("price", "30.5"),
                     new XElement("songs",
                         new XElement("title", "song1"),
                         new XElement("duration", "154"),
                         new XElement("title", "song2"),
                         new XElement("duration", "166"),
                         new XElement("title", "song3"),
                         new XElement("duration", "188"))
                         ),
                          new XElement("album",
                     new XElement("name", "Lava"),
                     new XElement("artist", "Jimmy Handix"),
                     new XElement("year", "1995"),
                     new XElement("producer", "Sony Music"),
                     new XElement("price", "30.5"),
                     new XElement("songs",
                         new XElement("title", "song1"),
                         new XElement("duration", "154"),
                         new XElement("title", "song2"),
                         new XElement("duration", "166"),
                         new XElement("title", "song3"),
                         new XElement("duration", "188"))
                         )
                         );
            XDocument doc = new XDocument();
            doc.Add(firstAlbum);
            doc.Save(XML_DOCUMENT);
        }

        public static void CollectArtistAndTheirAlbums()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(XML_DOCUMENT);
            XmlNode root = doc.DocumentElement;

            foreach (XmlNode child in root.ChildNodes)
            {
                string artist = child["artist"].InnerText;
                string albumName = child["name"].InnerText;
                if (artistsAndAlbums.ContainsKey(artist))
                {
                    artistsAndAlbums[artist].Add(albumName);
                }
                else
                {
                    artistsAndAlbums.Add(artist, new List<string> { albumName });
                }
            }
        }

        public static void CollectArtistAndTheirAlbumsUsingXPath()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(XML_DOCUMENT);
            XmlNode root = doc.DocumentElement;

            string xPathAlbums = "albums/album";

            XmlNodeList albums = doc.SelectNodes(xPathAlbums);
            foreach (XmlNode album in albums)
            {
                string artist = album.SelectSingleNode("artist").InnerText;
                string albumName = album.SelectSingleNode("name").InnerText;

                if (artistsAndAlbums.ContainsKey(artist))
                {
                    artistsAndAlbums[artist].Add(albumName);
                }
                else
                {
                    artistsAndAlbums.Add(artist, new List<string> { albumName });
                }
            }
        }

        public static void PrintArtistsAndAlbums()
        {
            foreach (var artist in artistsAndAlbums)
            {
                Console.WriteLine(artist.Key);
                foreach (var album in artist.Value)
                {
                    Console.WriteLine(album);
                    
                }
            }
        }

        public static void DeleteAllAlbumsWithPriceGreaterThan(decimal maxPrice)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(XML_DOCUMENT);

            XmlNode root = doc.DocumentElement;
            bool removePrevious = false;
            XmlNode lastNode = doc.DocumentElement;

            foreach (XmlNode child in root.ChildNodes)
            {
                if (removePrevious)
                {
                    removePrevious = false;
                    root.RemoveChild(lastNode);
                }

                decimal price = decimal.Parse(child["price"].InnerText);
                if (price > maxPrice)
                {
                    removePrevious = true;
                    lastNode = child;
                }
            }
            if (removePrevious)
            {
                removePrevious = false;
                root.RemoveChild(lastNode);
            }

            doc.Save("AfterRemoval.xml");

        }

        public static void ExtractAllSongNames()
        {
            XmlReader xmlreader = XmlReader.Create(XML_DOCUMENT);

            using (xmlreader)
            {
                while (xmlreader.Read())
                {
                    if (xmlreader.NodeType == XmlNodeType.Element&& xmlreader.Name == "title")
                    {
                        Console.WriteLine(xmlreader.ReadElementString());
                    }
                }
            }
        }

        public static void ExtractAllSongnamesUsingLINQ()
        {
            XDocument doc = XDocument.Load(XML_DOCUMENT);

            var songs =
               from album in doc.Descendants("album")
               from song in album.Descendants("songs")
               from title in album.Descendants("title")
               select title.Value;

            foreach (var song in songs)
            {
                Console.WriteLine(song);
            }
        }

        public static void ConvertIntoXmlFormat(string inputFilename, string outputFilename)
        {
            StreamReader inputFile = new StreamReader(inputFilename);
            using (inputFile)
            {
                XmlTextWriter xmlWriter = new XmlTextWriter(outputFilename, Encoding.UTF8);
                using(xmlWriter)
                {
                    xmlWriter.Formatting = Formatting.Indented;
                    xmlWriter.IndentChar = '\t';
                    xmlWriter.Indentation = 1;
                    xmlWriter.WriteStartDocument();
                    xmlWriter.WriteStartElement("people");

                    while (inputFile.EndOfStream == false)
                    {
                        xmlWriter.WriteStartElement("person");
                        string firstName = inputFile.ReadLine();
                        xmlWriter.WriteElementString("firstname", firstName);
                        string lastName = inputFile.ReadLine();
                        xmlWriter.WriteElementString("lastname", lastName);
                        string address = inputFile.ReadLine();
                        xmlWriter.WriteElementString("address", address);
                        string phone = inputFile.ReadLine();
                        xmlWriter.WriteElementString("phone", phone);
                        //reads empty line between people
                        inputFile.ReadLine();
                        xmlWriter.WriteEndElement();

                    }
                    xmlWriter.WriteEndDocument();
                }
            }
        }

        public static void ReadFormOneXmlAndWriteToAnother()
        {
            XmlReader input = XmlReader.Create(XML_DOCUMENT);

            using (input)
            {
                XmlTextWriter writer = new XmlTextWriter("album.xml",Encoding.UTF8);
                using (writer)
                {
                    writer.Formatting = Formatting.Indented;
                    writer.Indentation = 1;
                    writer.IndentChar = '\t';
                    writer.WriteStartDocument();
                    writer.WriteStartElement("albums");
                    while (input.Read())
                    {
                        if (input.NodeType == XmlNodeType.Element)
                        {
                            if (input.Name == "name")
                            {
                                writer.WriteStartElement("album");
                                writer.WriteElementString("name", input.ReadElementString());
                            }
                            else if (input.Name == "artist")
                            {
                                writer.WriteElementString("artist", input.ReadElementString());
                                writer.WriteEndElement();
                            }
                        }
                    }
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                }
            }
        }

        static void Main()
        {
            //WriteToXMLFile();
            //CollectArtistAndTheirAlbums();
            //CollectArtistAndTheirAlbumsUsingXPath();
            //PrintArtistsAndAlbums();
            //DeleteAllAlbumsWithPriceGreaterThan(20);
            //ExtractAllSongNames();
            //ExtractAllSongnamesUsingLINQ();
            //ConvertIntoXmlFormat("info.txt", "converted.xml");
            ReadFormOneXmlAndWriteToAnother();
        }
    }
}
